//
//  NSString+DD.m
//  need
//
//  Created by AcHu on 15/11/11.
//  Copyright (c) 2015年 oc. All rights reserved.
//

#import "NSString+DD.h"
#import <CommonCrypto/CommonDigest.h>




@implementation NSString (DD)
// 中文数字统计
- (NSInteger)textLength {
    NSInteger totalCount = 0;
    for (int i=0; i<self.length; i++) {
        unichar c = [self characterAtIndex:i];
        if (c >=0x4E00 && c <=0x9FFF)
        {
            totalCount ++;
            totalCount ++;
        } else {
            totalCount ++;
        }
    }
    return totalCount;
}

// 中文转拼音(全拼)
- (NSString *)chineseToPinyin {
    NSMutableString *source = [self mutableCopy];
    CFStringTransform((__bridge CFMutableStringRef)source, NULL, kCFStringTransformMandarinLatin, NO);
    CFStringTransform((__bridge CFMutableStringRef)source, NULL, kCFStringTransformStripDiacritics, NO);
    return source;
}

// 中文转拼音(首字母)
- (NSString *)chineseToShortPinyin {
    NSMutableString *source = [@"" mutableCopy];
    NSString *quanPinyin = [self chineseToPinyin];
    NSArray *captals = [quanPinyin componentsSeparatedByString:@" "];
    for (int i=0; i<captals.count; i++) {
        NSString *curStr = captals[i];
        if (![[curStr trim] isEmptyStr]) {
            NSString *captal = [[curStr trim] substringToIndex:1];
            [source appendString:captal];
        }
    }
    return source;
}

//md5-16位小写加密
- (NSString *)md5LowerCase16
{
    const char *cStr = [self UTF8String];
    unsigned char result[16];
    CC_MD5( cStr, (unsigned int) strlen(cStr), result);
    return [NSString stringWithFormat:
            @"%02X%02X%02X%02X%02X%02X%02X%02X",
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11]
            ];
}

//md5-32位小写加密
- (NSString *)md5LowerCase32
{
    const char *cStr = [self UTF8String];
    unsigned char result[16];
    CC_MD5( cStr, (unsigned int) strlen(cStr), result);
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
}

//md5-32位大写加密
- (NSString *)md5UpperCase32
{
    const char *cStr = [self UTF8String];
    unsigned char result[16];
    CC_MD5( cStr, (unsigned int) strlen(cStr), result);
    return [NSString stringWithFormat:
            @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ];
}

//json字符串转字典
-(NSDictionary *)dictionaryWithJsonString{
    if (self == nil) {
        return nil;
    }
    NSData *jsonData = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSError *err;
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                        options:NSJSONReadingMutableContainers
                                                          error:&err];
    
    if(err) {
        NSLog(@"json解析失败：%@",err);
        return nil;
    }
    return dic;
}

/**
 * 单行文本宽
 **/
-(CGFloat)wideTextFont:(UIFont *)font{
    if (!font) return CGSizeZero.width;
    
    if ([self isEmptyStr]) return CGSizeZero.width;
    
    CGSize size = CGSizeMake(MAXFLOAT,font.lineHeight + 2);
    
    //计算实际frame大小，并将label的frame变成实际大小
    CGSize txtSize;
    if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending) {
        NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
        CGRect txtRT = [self boundingRectWithSize:size options:options attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:10]} context:nil];
        txtSize = txtRT.size;
    } else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        txtSize = [self sizeWithFont:font constrainedToSize:size lineBreakMode:NSLineBreakByWordWrapping];
#pragma clang diagnostic pop
    }
    return txtSize.width;
}

// 计算文字的宽度 (高固定)
- (CGFloat)wideTextFont:(UIFont *)font
             viewHeight:(CGFloat)viewHeight{
    if (!font) return CGSizeZero.width;
    
    if ([self isEmptyStr]) return CGSizeZero.width;
    
    CGSize size = CGSizeMake(MAXFLOAT,viewHeight);
    
    //计算实际frame大小，并将label的frame变成实际大小
    CGSize txtSize;
    if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending) {
        NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
        CGRect txtRT = [self boundingRectWithSize:size options:options attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:10]} context:nil];
        txtSize = txtRT.size;
    } else {
        WarnDeprecatedStart
        txtSize = [self sizeWithFont:font constrainedToSize:size lineBreakMode:NSLineBreakByWordWrapping];
        WarnDeprecatedEnd
    }
    return txtSize.width;
}

// 计算文字的高度 (宽度固定)
- (CGFloat)heightTextFont:(UIFont *)font
                viewWidth:(CGFloat)viewWidth{
    if (!font || [self isEmptyStr]) return 0;
    
    CGSize size = CGSizeMake(viewWidth,MAXFLOAT);
    //计算实际frame大小，并将label的frame变成实际大小
    CGSize txtSize;
    if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending) {
        NSStringDrawingOptions options =  NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
        CGRect txtRT = [self boundingRectWithSize:size options:options attributes:@{NSFontAttributeName:font} context:nil];
        txtSize = txtRT.size;
    } else {
        WarnDeprecatedStart
        txtSize = [self sizeWithFont:font constrainedToSize:size lineBreakMode:NSLineBreakByWordWrapping];
        WarnDeprecatedEnd
    }
    return txtSize.height;
}

/**
 * 计算文本行数
 **/

-(NSInteger)numberOfLinesWithfont:(UIFont *)font
                       labelWidth:(CGFloat)labelWidth {
    UILabel *referLB = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, labelWidth, font.lineHeight)];
    referLB.numberOfLines = 0;
    referLB.text = self;
    CGFloat labelHeight = [referLB sizeThatFits:CGSizeMake(referLB.frame.size.width, MAXFLOAT)].height;
    NSInteger lines = @((labelHeight) / referLB.font.lineHeight).integerValue;
    return lines;
}

// 计算生肖
-(NSString *)shenXiao {
    int i= ([self intValue])%12;
    NSArray *names = @[@"猴",@"鸡",@"狗",@"猪",@"鼠",@"牛",@"虎",@"兔",@"龙",@"蛇",@"马",@"羊"];
    return names[i];
}


// 计算星座
-(NSString *)constellation
{
    if ([self isEmptyStr]) {
        return @"";
    }
    
    NSArray *arr = [self componentsSeparatedByString:@"-"];
    if ([arr count] != 3) {
        return @"";
    }
    int month = ((NSNumber*)[arr objectAtIndex:1]).intValue;
    int day = ((NSNumber*)[arr objectAtIndex:2]).intValue;
    
    switch (month)
    {
        case 1:
        {
            if(day >= 20)
            {
                return NSLocalizedString(@"水瓶座", @"水瓶座");
            }
            else
            {
                return NSLocalizedString(@"摩羯座",@"摩羯座");
            }
            break;
        }
            
        case 2:
        {
            if(day >= 19)
            {
                return NSLocalizedString(@"双鱼座",@"双鱼座");
            }
            else
            {
                return NSLocalizedString(@"水瓶座", @"水瓶座");;
            }
            break;
        }
            
        case 3:
        {
            if(day >= 21)
            {
                return NSLocalizedString(@"白羊座", @"白羊座");
            }
            else
            {
                return NSLocalizedString(@"双鱼座",@"双鱼座");
            }
            break;
        }
            
        case 4:
        {
            if(day >= 20)
            {
                return NSLocalizedString(@"金牛座",@"金牛座");
            }
            else
            {
                return NSLocalizedString(@"白羊座",@"白羊座");
            }
            break;
        }
            
        case 5:
        {
            if(day >= 21)
            {
                return NSLocalizedString(@"双子座",@"双子座");
            }
            else
            {
                return NSLocalizedString(@"金牛座",@"金牛座");
            }
            break;
        }
            
        case 6:
        {
            if(day >= 22)
            {
                return NSLocalizedString(@"巨蟹座",@"巨蟹座");
            }
            else
            {
                return NSLocalizedString(@"双子座",@"双子座");
            }
            break;
        }
            
        case 7:
        {
            if(day >= 23)
            {
                return NSLocalizedString(@"狮子座",@"狮子座");
            }
            else
            {
                return NSLocalizedString(@"巨蟹座",@"巨蟹座");
            }
            break;
        }
            
        case 8:
        {
            if(day >= 23)
            {
                return NSLocalizedString(@"处女座",@"处女座");
            }
            else
            {
                return NSLocalizedString(@"狮子座",@"狮子座");
            }
            break;
        }
            
        case 9:
        {
            if(day >= 23)
            {
                return NSLocalizedString(@"天秤座",@"天秤座");
            }
            else
            {
                return NSLocalizedString(@"处女座",@"处女座");
            }
            break;
        }
            
        case 10:
        {
            if(day >= 24)
            {
                return NSLocalizedString(@"天蝎座",@"天蝎座");
            }
            else
            {
                return NSLocalizedString(@"天秤座",@"天秤座");
            }
            break;
        }
            
        case 11:
        {
            if(day >= 23)
            {
                return NSLocalizedString(@"射手座",@"射手座");
            }
            else
            {
                return NSLocalizedString(@"天蝎座",@"天蝎座");
            }
            break;
        }
            
        case 12:
        {
            if(day >= 22)
            {
                return NSLocalizedString(@"摩羯座",@"摩羯座");
            }
            else
            {
                return NSLocalizedString(@"射手座",@"射手座");
            }
            break;
        }
    }
    return @"";
}

// 过滤电话号码里不合法的字符
- (NSString *)phoneNumberFilter{
    NSString *phoneStr = [self findNumFromStr];
    return phoneStr;
}

-(NSString *)findNumFromStr
{
    // Intermediate
    NSMutableString *numberString = [[NSMutableString alloc] init];
    NSString *tempStr;
    NSScanner *scanner = [NSScanner scannerWithString:self];
    // 设置在这些字符中匹配
    NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
    
    while (![scanner isAtEnd]) {
        // Throw away characters before the first number.
        [scanner scanUpToCharactersFromSet:numbers intoString:NULL];
        
        // Collect numbers.
        [scanner scanCharactersFromSet:numbers intoString:&tempStr];
        
        if ([tempStr isEmptyStr]) continue;
        
        [numberString appendString:tempStr];
        tempStr = @"";
    }
    // Result.
    return numberString;
}

// 字符串添加UTF8编码格式
- (NSString *)addUtf8String {
    return [self stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}

// 判断是否包含表情
- (BOOL)isContainsEmoji{
    __block BOOL returnValue = NO;
    [self enumerateSubstringsInRange:NSMakeRange(0, [self length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
     ^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
         
         const unichar hs = [substring characterAtIndex:0];
         // surrogate pair
         if (0xd800 <= hs && hs <= 0xdbff) {
             if (substring.length > 1) {
                 const unichar ls = [substring characterAtIndex:1];
                 const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                 if (0x1d000 <= uc && uc <= 0x1f77f) {
                     returnValue = YES;
                 }
             }
         } else if (substring.length > 1) {
             const unichar ls = [substring characterAtIndex:1];
             if (ls == 0x20e3) {
                 returnValue = YES;
             }
             
         } else {
             // non surrogate
             if (0x2100 <= hs && hs <= 0x27ff) {
                 returnValue = YES;
             } else if (0x2B05 <= hs && hs <= 0x2b07) {
                 returnValue = YES;
             } else if (0x2934 <= hs && hs <= 0x2935) {
                 returnValue = YES;
             } else if (0x3297 <= hs && hs <= 0x3299) {
                 returnValue = YES;
             } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                 returnValue = YES;
             }
         }
     }];
    
    return returnValue;
}




// 是否为整型
- (BOOL)isInt{
    NSScanner* scan = [NSScanner scannerWithString:self];
    int val;
    return[scan scanInt:&val] && [scan isAtEnd];
}

// 获取当前的系统语言
+ (NSString*)currentLanguage
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
    NSString *currentLang = [languages objectAtIndex:0];
    return currentLang;
}

// 判断当前的系统语言是否是中文
+ (BOOL)isChinese
{
    BOOL chinese = NO;
    if([[self currentLanguage] compare:@"zh-Hans" options:NSCaseInsensitiveSearch]==NSOrderedSame || [[self currentLanguage] compare:@"zh-Hant" options:NSCaseInsensitiveSearch]==NSOrderedSame)
    {
        chinese = YES;
    }else{
        chinese = NO;
    }
    return chinese;
}

// 生成图片名字 -- 根据当前时间的时间戳生成
+ (NSString*)createName
{
    CFUUIDRef newUniqueID = CFUUIDCreate(kCFAllocatorDefault);
    CFStringRef newUniqueIDString = CFUUIDCreateString(kCFAllocatorDefault, newUniqueID);
    NSString *guid = (__bridge NSString *)newUniqueIDString;
    CFRelease(newUniqueIDString);
    CFRelease(newUniqueID);
    return([NSString stringWithFormat:@"%lld%@",[[NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]]longLongValue],[guid lowercaseString]]);
}

/** 判断字符串包含 */
- (BOOL)isContactString:(NSString *)str {
    BOOL flag = NO;
    if ([str isEmptyStr]) return flag;
    
    NSRange foundObj = [self rangeOfString:str options:NSCaseInsensitiveSearch];
    if(foundObj.location != NSNotFound) {
        return YES;
    }
    return NO;
}

// 转换格式为千分格式
+ (NSString *)qianFen:(NSNumber *)number {
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc]init];
    formatter.numberStyle = NSNumberFormatterDecimalStyle;
    return [formatter stringFromNumber:number];
}

- (NSUInteger)numberOfLines {
    return [[self componentsSeparatedByString:@"\n"] count] + 1;
}

/**
 * 如果字符串为空就返回空字符串
 */
- (NSString *)filterString {
    NSString *ret = nil;
    if(nil == self)
    {
        ret = @"";
    }
    if([self isKindOfClass:[NSNull class]])
    {
        ret = @"";
    }
    if(YES == [@"" isEqualToString:[self trim]])
    {
        ret = @"";
    }
    if(0 == self.length)
    {
        ret = @"";
    } else {
        ret = self;
    }
    return ret;
}

//URLEncode
-(NSString*)urlEncode{
    NSString *encodedString = (NSString *)
    CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                              (CFStringRef)self,
                                                              NULL,
                                                              (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                              kCFStringEncodingUTF8));
    
    return encodedString;
}

//URLDEcode
-(NSString *)urlDecode
{
    //NSString *decodedString = [encodedString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding ];
    
    NSString *decodedString  = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL,
                                                                                                                     (__bridge CFStringRef)self,
                                                                                                                     CFSTR(""),
                                                                                                                     CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
    return decodedString;
}



/** 下面两个方法是关于字符串去除前后空格和内容是否为空 */
-(BOOL)isEmptyStr
{
    if(nil == self)
    {
        return YES;
    }
    if([self isKindOfClass:[NSNull class]])
    {
        return YES;
    }
    if(YES == [@"" isEqualToString:[self trim]])
    {
        return YES;
    }
    if(0 == self.length)
    {
        return YES;
    }
    return NO;
}

/**
 * 如果字符串为空就返回空字符串
 */
-(NSString *)defaultString {
    NSString *ret = nil;
    if(nil == self)
    {
        ret = @"";
    }
    if([self isKindOfClass:[NSNull class]])
    {
        ret = @"";
    }
    if(YES == [@"" isEqualToString:[self trim]])
    {
        ret = @"";
    }
    if(0 == self.length)
    {
        ret = @"";
    } else {
        ret = self;
    }
    return ret;
}

/** 去掉前后空格 */
-(NSString *)trim
{
    if(![self isKindOfClass:[NSString class]])
        return @"";
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

-(BOOL)isValidateLink{
    NSString *linkTypeRegex = @"((http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?;:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?;:_/=<>]*)?)";
    NSPredicate *linkTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",linkTypeRegex];
    return [linkTest evaluateWithObject:[self lowercaseString]];
}

-(NSString *)httpUrl{
    NSString *str = self;
    if ([str containsString:@"https"]) {
        NSArray *urlStrArr = [self componentsSeparatedByString:@"https"];
        str = [NSString stringWithFormat:@"http%@",urlStrArr.lastObject];
    }
    
    if (![str containsString:@"https"] && ![str containsString:@"http"]) {
        str = [NSString stringWithFormat:@"http://%@",str];
    }
    return str;
}

@end

